package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.api.contant.model.dto.CourseBaseDTO;
import com.xuecheng.api.contant.model.qo.QueryCourseBaseModel;
import com.xuecheng.common.domain.page.PageRequestParams;
import com.xuecheng.common.domain.page.PageVO;
import com.xuecheng.common.enums.common.CommonEnum;
import com.xuecheng.common.enums.content.CourseAuditEnum;
import com.xuecheng.common.enums.content.CourseChargeEnum;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.common.util.StringUtil;
import com.xuecheng.content.common.constant.ContentErrorCode;
import com.xuecheng.content.convert.CourseBaseConvert;
import com.xuecheng.content.entity.CourseBase;
import com.xuecheng.content.entity.CourseMarket;
import com.xuecheng.content.mapper.CourseBaseMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.xuecheng.content.service.CourseMarketService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 课程基本信息 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class CourseBaseServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase> implements CourseBaseService {

    @Autowired
    private CourseMarketService courseMarketService;


    /**
     * 课程审核
     * @param courseBaseDTO 课程基本信息封装
     */
    @Override
    @Transactional
    public void approve(CourseBaseDTO courseBaseDTO) {
        /*
         * 业务分析：
         *   1.判断关键数据
         *       auditMind  auditStatus  courseid
         *
         *   2.判断业务数据
         *       课程基础信息
         *           判断是否存在
         *           判断是否删除
         *           判断审核状态
         *               必须为：已提交
         *       审核状态
         *           运营平台只能给课程审核状态赋值：审核通过、审核未通过
         *   3.修改课程审核信息
         *       auditMind  auditStatus  auditNum（每次+1）
         * */
        // 1、判断关键数据 和业务数据
        // 审核意见
        if (StringUtil.isBlank(courseBaseDTO.getAuditMind())
        ) {
            ExceptionCast.cast(ContentErrorCode.E_120022);
        }
        // 课程信息id
        if (ObjectUtils.isEmpty(courseBaseDTO.getCourseBaseId())) {
            ExceptionCast.cast(ContentErrorCode.E_120019);
        }
        // 业务数据判断
        if (courseBaseDTO.getAuditStatus().equals(CourseAuditEnum.AUDIT_UNPAST_STATUS.getCode()) ||
                courseBaseDTO.getAuditStatus().equals(CourseAuditEnum.AUDIT_PUBLISHED_STATUS.getCode()) ||
                courseBaseDTO.getAuditStatus().equals(CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode())
        ) {
            ExceptionCast.cast(ContentErrorCode.E_120015);
        }

        CourseBase courseBase = this.getById(courseBaseDTO.getCourseBaseId());
        // 课程信息判断
        if (ObjectUtils.isEmpty(courseBase)) {
            ExceptionCast.cast(ContentErrorCode.E_120013);
        }
        // 必须为已提交
        if (!courseBase.getAuditStatus().equals(CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode())) {
            ExceptionCast.cast(ContentErrorCode.E_120015);
        }
        //是否删除
        if (courseBase.getStatus().equals(CommonEnum.DELETE_FLAG.getCodeInt())) {
            ExceptionCast.cast(ContentErrorCode.E_120021);
        }
        // 获取当前数据库中的次数
        courseBase.setAuditMind(courseBaseDTO.getAuditMind());
        courseBase.setAuditStatus(courseBaseDTO.getAuditStatus());
        Integer auditNums = courseBase.getAuditNums();
        courseBase.setAuditNums(auditNums+1);
        boolean flag = this.updateById(courseBase);
        if (!flag){
            ExceptionCast.cast(ContentErrorCode.E_120015);
        }
    }

    /**
     * 根据课程Id提交课程信息
     *
     * @param courseBaseId 课程id
     * @param companyId    机构id
     **/
    @Override
    @Transactional
    public void commitCourseBase(Long courseBaseId, Long companyId) {
        // 1、判断关键按数据
        if (ObjectUtils.isEmpty(companyId)) {
            ExceptionCast.cast(ContentErrorCode.E_120018);
        }
        if (ObjectUtils.isEmpty(courseBaseId)) {
            ExceptionCast.cast(ContentErrorCode.E_120019);
        }
        // 2、判断业务数据
        CourseBase courseBase = this.getById(courseBaseId);
        // 判断课程基本信息是否为空
        if (ObjectUtils.isEmpty(courseBase)) {
            ExceptionCast.cast(ContentErrorCode.E_120013);
        }
        // 判断是否是同一家机构
        if (!courseBase.getCompanyId().equals(companyId)) {
            ExceptionCast.cast(ContentErrorCode.E_120020);
        }
        // 判断当前课程基本信息是否为空
        if (courseBase.getStatus().equals(CommonEnum.DELETE_FLAG.getCodeInt())) {
            ExceptionCast.cast(ContentErrorCode.E_120021);
        }
        // 审核状态
        if (courseBase.getAuditStatus().equals(CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode())
                || courseBase.getAuditStatus().equals(CourseAuditEnum.AUDIT_PASTED_STATUS.getCode())
                || courseBase.getAuditStatus().equals(CourseAuditEnum.AUDIT_PUBLISHED_STATUS.getCode())
        ) {
            ExceptionCast.cast(ContentErrorCode.E_120015);
        }
        // 3、修改课程审核状态
        LambdaUpdateWrapper<CourseBase> wrapper = new LambdaUpdateWrapper<>();
        // 课程基本信息id
        wrapper.eq(CourseBase::getId, courseBaseId);
        // 机构id
        wrapper.eq(CourseBase::getCompanyId, companyId);
        // 设置为提交状态
        wrapper.set(CourseBase::getAuditStatus, CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode());
        // 调用方法
        boolean flag = this.update(courseBase,wrapper);
        if (!flag){
            ExceptionCast.cast(ContentErrorCode.E_120017);
        }
    }

    /**
     * 删除课程基本信息
     *
     * @param courseBaseId 课程基本信息id
     */
    @Override
    @Transactional
    public void removeCourseBase(Long courseBaseId, Long companyId) {
        // 1、判断关键逻辑
        if (ObjectUtils.isEmpty(companyId)) {
            ExceptionCast.cast(ContentErrorCode.E_120018);
        }
        if (companyId < 1) {
            ExceptionCast.cast(ContentErrorCode.E_120023);
        }
        CourseBase base = this.getById(courseBaseId);
        if (ObjectUtils.isEmpty(base)) {
            ExceptionCast.cast(ContentErrorCode.E_120013);
        }
        // 2、判断业务数据
        CourseBase courseBase = this.getById(courseBaseId);

        if (courseBase.getAuditStatus().equals(CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode())
        ) {
            ExceptionCast.cast(ContentErrorCode.E_120014);
        }
        if (courseBase.getAuditStatus().equals(CourseAuditEnum.AUDIT_PASTED_STATUS.getCode())) {
            ExceptionCast.cast(ContentErrorCode.E_120015);
        }
        if (courseBase.getAuditStatus().equals(CourseAuditEnum.AUDIT_PUBLISHED_STATUS.getCode())) {
            ExceptionCast.cast(ContentErrorCode.E_120014);
        }
        // 3、删除数据内容,修改状态
        // 机构隔离
        if (!courseBase.getCompanyId().equals(companyId)) {
            ExceptionCast.cast(ContentErrorCode.E_120020);
        }
        LambdaUpdateWrapper<CourseBase> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(CourseBase::getCompanyId, companyId);
        wrapper.eq(CourseBase::getId,courseBaseId);
        wrapper.set(CourseBase::getStatus, CommonEnum.DELETE_FLAG.getCodeInt());
        boolean flag = this.update(wrapper);
        if (!flag){
            ExceptionCast.cast(ContentErrorCode.E_120025);
        }
    }

    /**
     * 修改课程基础信息
     *
     * @param dto CourseBaseDTO
     * @return 返回CourseBaseDTO
     */
    @Override
    @Transactional
    public CourseBaseDTO modifyCourseBase(CourseBaseDTO dto) {
        // 1、判断关键数据
        verifyCourseDTO(dto);
        if (dto.getCompanyId() < 1) {
            ExceptionCast.cast(ContentErrorCode.E_120023);
        }
        // 课程信息id必须存在
        if (ObjectUtils.isEmpty(dto.getCourseBaseId())) {
            ExceptionCast.cast(ContentErrorCode.E_120013);
        }
        // 2、判断业务数据
        CourseBase courseBase = this.getById(dto.getCourseBaseId());
        if (ObjectUtils.isEmpty(courseBase)) {
            ExceptionCast.cast(ContentErrorCode.E_120013);
        }
        if (!courseBase.getCompanyId().equals(dto.getCompanyId())) {
            ExceptionCast.cast(ContentErrorCode.E_120020);
        }
        if (courseBase.getStatus().equals(CommonEnum.DELETE_FLAG.getCodeInt())) {
            ExceptionCast.cast(ContentErrorCode.E_120021);
        }
        if (courseBase.getAuditStatus().equals(CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode())
                || courseBase.getAuditStatus().equals(CourseAuditEnum.AUDIT_PASTED_STATUS.getCode())
                || courseBase.getAuditStatus().equals(CourseAuditEnum.AUDIT_PUBLISHED_STATUS.getCode())
        ) {
            ExceptionCast.cast(ContentErrorCode.E_120014);
        }
        // 根据课程信息id条件查询
        LambdaQueryWrapper<CourseMarket> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CourseMarket::getCourseId, dto.getCourseBaseId());
        CourseMarket courseMarket = courseMarketService.getOne(wrapper);
        if (ObjectUtils.isEmpty(courseMarket)) {
            ExceptionCast.cast(ContentErrorCode.E_120101);
        }
        // 3.修改数据内容
        CourseBase po = CourseBaseConvert.INSTANCE.dto2entity(dto);
        po.setChangeDate(LocalDateTime.now());
        po.setAuditStatus(CourseAuditEnum.AUDIT_UNPAST_STATUS.getCode());

        boolean flag = this.updateById(po);
        if (!flag) {
            ExceptionCast.cast(ContentErrorCode.E_120024);
        }
        CourseMarket market = new CourseMarket();
        market.setCharge(dto.getCharge());
        if (CourseChargeEnum.CHARGE_YES.getCode().equals(market.getCharge())) {
            if (market.getPrice() != null) {
                market.setPrice(dto.getPrice());
            }
        }
        LambdaQueryWrapper<CourseMarket> courseMarketLambdaQueryWrapper = new LambdaQueryWrapper<>();
        courseMarketLambdaQueryWrapper.eq(CourseMarket::getCourseId, dto.getCourseBaseId());
        boolean marketResult = courseMarketService.update(market, courseMarketLambdaQueryWrapper);
        if (!marketResult) {
            throw new RuntimeException("修改课程营销失败");
        }
        // 4.返回前端最新的数据库的数据并封装为dto返回
        CourseBaseDTO courseBaseDTO = CourseBaseConvert.INSTANCE.entity2dto(po);
        courseBaseDTO.setCharge(dto.getCharge());
        courseBaseDTO.setPrice(dto.getPrice());
        return courseBaseDTO;
    }

    /**
     * 根据Id查询课程基础信息
     *
     * @param courseBaseId 课程的Id值
     * @param companyId    公司的Id值
     * @return CourseBaseDTO
     */
    @Override
    public CourseBaseDTO getByCourseId(Long courseBaseId, Long companyId) {
        // 1、判断关键数据
        // 课程基础信息id是否为空
        if (ObjectUtils.isEmpty(courseBaseId)) {
            ExceptionCast.cast(ContentErrorCode.E_120019);
        }
        // 机构id是否为空
        if (ObjectUtils.isEmpty(companyId)) {
            ExceptionCast.cast(ContentErrorCode.E_120018);
        }
        // 2、判断业务数据
        CourseBase courseBase = this.getById(courseBaseId);
        // 课程基本信息是否为空
        if (ObjectUtils.isEmpty(courseBase)) {
            ExceptionCast.cast(ContentErrorCode.E_120013);
        }
        // 判断是否是同一家机构
        if (!courseBase.getCompanyId().equals(companyId)) {
            ExceptionCast.cast(ContentErrorCode.E_120020);
        }
        // 判断是否是删除状态
        if (courseBase.getStatus().equals(CommonEnum.DELETE_FLAG.getCodeInt())) {
            ExceptionCast.cast(ContentErrorCode.E_120021);
        }
        // 判断审核状态
        if (courseBase.getAuditStatus().equals(CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode())
                || courseBase.getAuditStatus().equals(CourseAuditEnum.AUDIT_PASTED_STATUS.getCode())
                || courseBase.getAuditStatus().equals(CourseAuditEnum.AUDIT_PUBLISHED_STATUS.getCode())
        ) {
            ExceptionCast.cast(ContentErrorCode.E_120014);
        }
        // 根据课程信息id查询market
        LambdaQueryWrapper<CourseMarket> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CourseMarket::getCourseId, courseBaseId);
        CourseMarket courseMarket = courseMarketService.getOne(wrapper);
        // 判断媒资信息是否为空
        if (ObjectUtils.isEmpty(courseMarket)) {
            ExceptionCast.cast(ContentErrorCode.E_120102);
        }
        // 3、查询数据并转为dto返回
        CourseBaseDTO baseDTO = CourseBaseConvert.INSTANCE.entity2dto(courseBase);
        return baseDTO;
    }

    /**
     * 课程基础信息添加
     *
     * @param dto CourseBaseDTO  课程基础信息封装类（数据传输对象）
     * @return CourseBaseDTO 课程基础信息封装类（数据传输对象）
     */
    @Override
    @Transactional
    public CourseBaseDTO createCourseBase(CourseBaseDTO dto) {
        // 1、判断关键数据
        verifyCourseDTO(dto);
        // 2、将数据转换
        CourseBase courseBase = CourseBaseConvert.INSTANCE.dto2entity(dto);
        // 3、是否要给数据赋值默认内容 --> 1、删除状态 2、课程审核状态
        courseBase.setStatus(CommonEnum.USING_FLAG.getCodeInt());
        courseBase.setAuditStatus(CourseAuditEnum.AUDIT_UNPAST_STATUS.getCode());
        // 4、保存数据到数据库中
        boolean save = this.save(courseBase);
        // 5、判断对数据操作的结果 1、课程基本信息 2、课程营销
        if (!save) {
            ExceptionCast.cast(ContentErrorCode.E_120001);
        }
        // 创建新的媒资对象
        CourseMarket courseMarket = new CourseMarket();
        // 赋值课程基础信息id
        courseMarket.setCourseId(courseBase.getId());
        courseMarket.setCharge(dto.getCharge());
        // 判断课程是否收费,收费的课程需要判断价格是否为空
        if (CourseChargeEnum.CHARGE_YES.getCode().equals(dto.getCharge())) {
            if (ObjectUtils.isEmpty(dto.getPrice())) {
                ExceptionCast.cast(ContentErrorCode.E_120110);
            }
            BigDecimal price = dto.getPrice();
            courseMarket.setPrice(price);
        }
        boolean marketResult = courseMarketService.save(courseMarket);
        if (!marketResult) {
            // 保存课程营销信息失败
            ExceptionCast.cast(ContentErrorCode.E_120107);
        }
        //将数据库最新的数据转换为dto并返回
        CourseBase po = this.getById(courseBase.getId());
        CourseBaseDTO resultDTO = CourseBaseConvert.INSTANCE.entity2dto(po);
        resultDTO.setPrice(dto.getPrice());
        resultDTO.setCharge(dto.getCharge());
        return resultDTO;
    }

    // 将判断关键数据封装
    private void verifyCourseDTO(CourseBaseDTO dto) {
        // 机构是否为空
        if (ObjectUtils.isEmpty(dto.getCompanyId())) {
            ExceptionCast.cast(ContentErrorCode.E_120018);
        }
        // 机构名称是否为空
        if (StringUtil.isBlank(dto.getName())) {
            ExceptionCast.cast(ContentErrorCode.E_120004);
        }
        // 大分类是否为空
        if (StringUtil.isBlank(dto.getMt())) {
            ExceptionCast.cast(ContentErrorCode.E_120002);
        }
        // 小分类是否为空
        if (StringUtil.isBlank(dto.getSt())) {
            ExceptionCast.cast(ContentErrorCode.E_120003);
        }
        // 等级是否为空
        if (StringUtil.isBlank(dto.getGrade())) {
            ExceptionCast.cast(ContentErrorCode.E_120007);
        }
        // 教育模式是否为空
        if (StringUtil.isBlank(dto.getTeachmode())) {
            ExceptionCast.cast(ContentErrorCode.E_120006);
        }
    }


    /**
     * 分页条件查询课程基本信息数据
     *
     * @param params    {@link PageRequestParams} 分页封装数据
     * @param model     {@link QueryCourseBaseModel} 条件查询封装数据
     * @param companyId Long 机构id
     * @return PageVO 分页结果封装数据
     */
    @Override
    public PageVO queryCourseBaseList(PageRequestParams params, QueryCourseBaseModel model, Long companyId) {
            // 1.判断关键数据
            // 分页数据的合法性
            if (params.getPageNo() < 1) {
                params.setPageNo(PageRequestParams.DEFAULT_PAGE_NUM);
            }
            if (params.getPageSize() < 1) {
                params.setPageSize(PageRequestParams.DEFAULT_PAGE_SIZE);
            }

            // 2.构建分页对象
            Page<CourseBase> basePage = new Page<>(params.getPageNo(), params.getPageSize());

            // 3.构建查询条件对象
            LambdaQueryWrapper<CourseBase> wrapper = new LambdaQueryWrapper<>();

            // 过滤删除的课程,只显示status为1的课程
            wrapper.eq(CourseBase::getStatus, CommonEnum.USING_FLAG.getCodeInt());

            // 课程审核状态查询条件 eq
            wrapper.eq(StringUtil.isNotBlank(model.getAuditStatus()), CourseBase::getAuditStatus, model.getAuditStatus());

            // todo:如果id不等于当前code,则是机构
            if (companyId != ContentErrorCode.E_120000.getCode()){
                // 课程名称查询条件 like
                wrapper.like(StringUtil.isNotBlank(model.getCourseName()), CourseBase::getName, model.getCourseName());
                // 添加对公司id的查询条件
                wrapper.eq(CourseBase::getCompanyId, companyId);
            }

            // 4.查询数据内容获得结果
            Page<CourseBase> page = this.page(basePage, wrapper);

            // 获取当前页数据
            List<CourseBase> records = page.getRecords();
            // 获取总条数
            long total = page.getTotal();
            // 创建一个空的集合
            List<CourseBaseDTO> dtos = Collections.emptyList();
            // 判断当前页是否为空
            if (!(CollectionUtils.isEmpty(records))) {
                dtos = CourseBaseConvert.INSTANCE.entitys2dtos(records);
            }
            // 5.构建返回结果数据-PageVo
            PageVO pageVO = new PageVO(dtos, total, params.getPageNo(), params.getPageSize());

            return pageVO;

    }


    /**
     * 查询课程基本信息
     *
     * @return List<CourseBase> 课程基本信息的集合
     */
    @Override
    public List<CourseBase> queryAll() {
        List<CourseBase> result = list();
        return result;
    }
}
